#include <buola/scene.h>
#include <buola/scene/csceneview.h>
#include <buola/scene/ccamera.h>
#include <buola/scene/cperspectivecamera.h>
#include <buola/scene/cscene.h>
#include <buola/scene/geodes/ccube.h>
#include <buola/scene/transform/crttransform.h>
#include <buola/scene/cimagerenderer.h>
#include <buola/image/io.h>
#include <buola/image/cgc.h>
#include <buola/gui/ctoolkit.h>
#include <buola/app/capp.h>

using namespace buola;

int main(int pNArg,char **pArgs)
{
    buola_init(pNArg,pArgs);

    try
    {
        CApp lApp;

        gui::get_toolkit()->GetOpenGLGC()->MakeCurrent();
        
        //create the scene
        scene::PScene lScene=new scene::CScene;
        
        scene::PCube lCube1=new scene::CCube;
        scene::PRTTransform lTransform1=new scene::CRTTransform;
        lCube1->AttachTo(lTransform1);
        lScene->World()->AddChild(lTransform1);

        scene::PCube lCube2=new scene::CCube;
        scene::PRTTransform lTransform2=new scene::CRTTransform(mat::CQuat_d(),{0,3,0});
        lCube2->AttachTo(lTransform2);
        lScene->World()->AddChild(lTransform2);

        scene::PCube lCube3=new scene::CCube;
        scene::PRTTransform lTransform3=new scene::CRTTransform(mat::CQuat_d(),{0,1.5,2});
        lCube3->AttachTo(lTransform3);
        lScene->World()->AddChild(lTransform3);

        scene::PCube lCube4=new scene::CCube;
        scene::PRTTransform lTransform4=new scene::CRTTransform(mat::CQuat_d(),{-4,1,0});
        lCube4->AttachTo(lTransform4);
        lScene->World()->AddChild(lTransform4);

        scene::PCube lCube5=new scene::CCube;
        scene::PRTTransform lTransform5=new scene::CRTTransform(mat::CQuat_d(),{-4,1.5,2});
        lCube5->AttachTo(lTransform5);
        lScene->World()->AddChild(lTransform5);

        scene::PCube lCube6=new scene::CCube;
        scene::PRTTransform lTransform6=new scene::CRTTransform(mat::CQuat_d(),{-2,-3,0});
        lCube6->AttachTo(lTransform6);
        lScene->World()->AddChild(lTransform6);

        scene::PPerspectiveCamera lCamera=new scene::CPerspectiveCamera;
        lCamera->LookAt({100,100,0});
        lCamera->LookAt({-2,1,1},{15,12,12},{0,0,1});

        scene::CImageRenderer lRenderer;
        lRenderer.SetCamera(lCamera);
        lRenderer.AddScene(lScene);

        img::CImage_rgb8 lImage({640,640});
        
        lRenderer.GetImage(lImage);

        img::save(lImage,io::file("scene.ppm"));
        
        scene::PSceneView lView=new scene::CSceneView;
        lView->SetCamera(lCamera);
        lView->AddScene(lScene);
        lView->Map(CSize_d(800,600));
        
        lApp.Run();
    }
    catch(std::exception &pE)
    {
        msg_info() << pE.what() << "\n";
    }

    return buola_finish();
}